/*
 * 文件名：at_command.cpp
 * 功能描述：AT指令处理和串口通信
 */

#include "at_command.h"
#include "ElectromagnetControl.h"
#include "buzzer.h"
#include "LEDControl.h"
#include "OTAUpdate.h"
#include "middle.h"
#include <screen.h>
#include <nvs_flash.h>
#include <esp_efuse.h>
#include <esp_system.h>
#include "bsp_ble.h" // 添加蓝牙相关头文件
#include "config.h"
// 串口任务句柄
static TaskHandle_t uartTaskHandle = NULL;

// 串口任务函数：监听串口输入
void uartTask(void *pvParameters)
{
  if (print_key)
    Serial.println("AT_init");
  while (1)
  {
    // Serial.println("AT");
    processSerialInput();                // 处理串口输入
    vTaskDelay(10 / portTICK_PERIOD_MS); // 降低CPU占用
  }
}

// 初始化串口任务
void at_com_init()
{
  xTaskCreatePinnedToCore(
      uartTask,        // 任务函数
      "UART Task",     // 任务名称
      4096,            // 栈大小
      NULL,            // 参数
      1,               // 优先级
      &uartTaskHandle, // 任务句柄
      1                // 核心
  );
}

// 处理串口输入
void processSerialInput()
{
  static String inputBuffer = "";
  static bool commandReady = false;

  while (Serial.available())
  {
    char ch = (char)Serial.read();
    if (ch == '\n')
    {
      commandReady = true;
    }
    else
    {
      inputBuffer += ch;
    }
  }

  if (commandReady)
  {
    handleCommand(inputBuffer); // 处理指令
    inputBuffer = "";           // 清空缓冲区
    commandReady = false;       // 重置状态
  }
}
// 定义NVS命名空间和键名
#define NVS_NAMESPACE "device_cfg"
#define NVS_KEY_SN "serial_number"

// 初始化非易失性存储器
void initialize_nvs()
{
  esp_err_t ret = nvs_flash_init();
  if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
  {
    ESP_ERROR_CHECK(nvs_flash_erase());
    ret = nvs_flash_init();
  }
  ESP_ERROR_CHECK(ret);
}

// 获取芯片的唯一标识符
String get_chip_uuid()
{
  // 获取芯片的MAC地址
  uint64_t chipid = ESP.getEfuseMac();
  // 定义一个字符数组，用于存储UUID
  char uuid[32];
  // 将MAC地址转换为UUID格式
  snprintf(uuid, sizeof(uuid), "%08X%08X",
           (uint32_t)(chipid >> 32),
           (uint32_t)chipid);
  // 返回UUID字符串
  return String(uuid);
}
// 处理 AT 指令
void handleCommand(const String &cmdIn)
{
  String cmd = cmdIn;
  cmd.trim();

  if (cmd == "AT+STATUS?")
  {
    if (print_key)
    {
      Serial.printf("X限位: %5d\n", calibration_x_g);
      Serial.printf("Y限位: %5d\n", calibration_y_g);
      Serial.printf("ID板: %5d\n", id_status);
      Serial.printf("BLE: %5d\n", deviceConnected_g);
      Serial.printf("WiFi: %5d\n", wifi_status_g);
      Serial.printf("语音模块: %d\n", speaker_g);
      Serial.printf("电量: %5d %%\n", batteryLevel_g);
      Serial.printf("充电状态: %d\n", Charging_status);
      Serial.printf("模式: %5d\n", mode_g);
      Serial.printf("难度: %5d\n", level_difficulty_g);
      Serial.printf("速度: %5d\n", get_current_speed());
      Serial.printf("音量: %5d\n", beepLevel_g);
    }
  }
  else if (cmd == "AT+FWINFO?")
  {
    loadPreferences();

    if (print_key)
    {
      Serial.println("FW_NAME=" + firmware_name_g);
      Serial.println("FW_VER=" + firmware_version_g);
      Serial.println("SN=" + sn_g);
    }
  }
  else if (cmd.startsWith("AT+RES"))
  {
    // 执行重启操作
    if (print_key)
    {
      Serial.println("Rebooting device...");
    }
    ESP.restart(); // 重启设备
  }
  else if (cmd.startsWith("AT+MAGNET="))
  {                                 // 新增电磁铁控制指令
    String val = cmd.substring(10); // 获取指令后的数字
    int magnetId = val.toInt();     // 将字符串转换为整数

    // 控制电磁铁
    if (magnetId == 1)
    {
      setElectromagnet(1);
      controlElectromagnet(true);
      if (print_key)
      {
        Serial.println("OK");
      }
    }
    else if (magnetId == 2)
    {
      setElectromagnet(2);
      controlElectromagnet(true);
      if (print_key)
      {
        Serial.println("OK");
      }
    }
    else if (magnetId == 3)
    {
      setElectromagnet(3);
      controlElectromagnet(true);
      if (print_key)
      {
        Serial.println("OK");
      }
    }
    else if (magnetId == 4)
    {
      setElectromagnet(4);
      controlElectromagnet(true);
      if (print_key)
      {
        Serial.println("OK");
      }
    }
    else if (magnetId == 5)
    {
      setElectromagnet(5);
      controlElectromagnet(true);
      if (print_key)
      {
        Serial.println("OK");
      }
    }
    else
    {
      if (print_key)
      {
        Serial.println("ERROR: Invalid magnet number");
      }
    }
  }
  else if (cmd.startsWith("AT+MAGNETOFF="))
  {                                 // 新增电磁铁关闭指令
    String val = cmd.substring(13); // 获取指令后的数字
    int magnetId = val.toInt();     // 将字符串转换为整数

    // 关闭电磁铁
    if (magnetId == 1)
    {
      setElectromagnet(1);
      controlElectromagnet(false);
      if (print_key)
      {
        Serial.println("OK");
      }
    }
    else if (magnetId == 2)
    {
      setElectromagnet(2);
      controlElectromagnet(false);
      if (print_key)
      {
        Serial.println("OK");
      }
    }
    else if (magnetId == 3)
    {
      setElectromagnet(3);
      controlElectromagnet(false);
      if (print_key)
      {
        Serial.println("OK");
      }
    }
    else if (magnetId == 4)
    {
      setElectromagnet(4);
      controlElectromagnet(false);
      if (print_key)
      {
        Serial.println("OK");
      }
    }
    else if (magnetId == 5)
    {
      setElectromagnet(5);
      controlElectromagnet(false);
      if (print_key)
      {
        Serial.println("OK");
      }
    }
    else
    {
      if (print_key)
      {
        Serial.println("ERROR: Invalid magnet number");
      }
    }
  }
  else if (cmd.startsWith("AT+BUZZER="))
  {                                 // 新增蜂鸣器控制指令
    String val = cmd.substring(10); // 获取持续时间
    int duration = val.toInt();     // 转换为秒

    if (duration > 0)
    {
      playBuzzer(beepLevel_g, duration, 50);
      if (print_key)
      {
        Serial.print("OK");
      }
    }
    else
    {
      if (print_key)
      {
        Serial.println("ERROR: Invalid duration");
      }
    }
  }
  else if (cmd.startsWith("AT+LED_COLOR="))
  {                                 // 新增设置 WS2812 LED 颜色的指令
    String val = cmd.substring(13); // 获取颜色值 (R,G,B)
    int r, g, b;

    // 提取 RGB 值
    int comma1 = val.indexOf(',');
    int comma2 = val.indexOf(',', comma1 + 1);
    if (comma1 != -1 && comma2 != -1)
    {
      r = val.substring(0, comma1).toInt();
      g = val.substring(comma1 + 1, comma2).toInt();
      b = val.substring(comma2 + 1).toInt();

      if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255)
      {
        // 设置 WS2812 LED 颜色
        setConstantColor(0, r, g, b);
        if (print_key)
        {
          Serial.println("OK");
        }
      }
      else
      {
        if (print_key)
        {
          Serial.println("ERROR: Invalid color values");
        }
      }
    }
    else
    {
      if (print_key)
      {
        Serial.println("ERROR: Invalid color format");
      }
    }
  }
  else if (cmd == "AT+LED_OFF")
  { // 新增关掉 WS2812 LED 的指令
    turnOffLED(0);
    if (print_key)
    {
      Serial.println("OK");
    }
  }
  else if (cmd.startsWith("AT+SET_NAME="))
  {
    String fw_name = cmd.substring(12); // 提取名称
    if (fw_name.length() > 0 && fw_name.length() < 32)
    {
      firmware_name_g = fw_name;
      savePreferences();
      if (print_key)
      {
        Serial.println("OK");
      }
    }
    else
    {
      if (print_key)
      {
        Serial.println("ERROR: Invalid name");
      }
    }
  }
  else if (cmd.startsWith("AT+SET_FW="))
  {
    String fw = cmd.substring(10);
    if (fw.length() > 0 && fw.length() < 32)
    {
      firmware_version_g = fw;
      savePreferences();
      if (print_key)
      {
        Serial.println("OK");
      }
    }
    else
    {
      if (print_key)
      {
        Serial.println("ERROR: Invalid FW version");
      }
    }
  }
  else if (cmd.startsWith("AT+SET_SN="))
  {
    String sn = cmd.substring(10);
    sn.trim();

    // 如果SN号长度不为13，则返回错误
    if (sn.length() != 13)
    {
      if (print_key)
      {
        Serial.println("ERR:SN_LENGTH");
      }
      return;
    }

    // 检查SN码的后8位是否全是0
    String snSuffix = sn.substring(sn.length() - 8);
    if (snSuffix == "00000000")
    {
      if (print_key)
      {
        Serial.println("ERR:SN_INVALID");
      }
      return;
    }

    // 打开NVS - 使用与loadPreferences相同的命名空间
    nvs_handle_t handle;
    esp_err_t err;

    if ((err = nvs_open("settings", NVS_READWRITE, &handle)) != ESP_OK)
    {
      if (print_key)
      {
        Serial.printf("ERR:NVS_OPEN:%d\n", err);
      }
      return;
    }

    // 将SN号写入NVS - 使用与loadPreferences相同的键名
    if ((err = nvs_set_str(handle, "s_n_g", sn.c_str())) != ESP_OK)
    {
      if (print_key)
      {
        Serial.printf("ERR:NVS_WRITE:%d\n", err);
      }
      nvs_close(handle);
      return;
    }

    // 提交NVS
    if ((err = nvs_commit(handle)) != ESP_OK)
    {
      if (print_key)
      {
        Serial.printf("ERR:NVS_COMMIT:%d\n", err);
      }
      nvs_close(handle);
      return;
    }

    // 关闭NVS
    nvs_close(handle);

    // 更新全局SN变量
    sn_g = sn;

    // 使用完整13位SN更新蓝牙名称
    String newBleName = "CB_" + sn;
    if (print_key)
    {
      Serial.printf("设置新的蓝牙名称: %s\n", newBleName.c_str());
    }
    ble_g.setName(newBleName);

    if (print_key)
    {
      Serial.println("OK:SN_SAVED");
    }
    return;
  }
  else if (cmd.startsWith("AT+GET_UUID"))
  {
    if (print_key)
    {
      Serial.println("UUID:" + get_chip_uuid());
    }
    return;
  }
  // 如果命令是GET_SN，则读取SN号
  if (cmd == "AT+GET_SN")
  {
    nvs_handle_t handle;
    char sn[15] = {0};
    // 使用与loadPreferences相同的命名空间
    if (nvs_open("settings", NVS_READONLY, &handle) == ESP_OK)
    {
      size_t len = sizeof(sn);
      // 使用与loadPreferences相同的键名
      nvs_get_str(handle, "s_n_g", sn, &len);
      nvs_close(handle);
      if (print_key)
      {
        Serial.printf("SN:%s\n", sn);
      }
      return;
    }
    if (print_key)
    {
      Serial.println("ERR:SN_READ");
    }
    return;
  }
  else if (cmd.startsWith("AT+SET_SPEED="))
  {
    String val = cmd.substring(13);
    int newSpeed = val.toInt();
    update_speed(newSpeed);
    speed_set(newSpeed);
    savePreferences();
    if (print_key)
    {
      Serial.println("OK");
    }
  }
  else if (cmd.startsWith("AT+SET_BEEP="))
  {
    String val = cmd.substring(12);
    int newBeep = val.toInt();
    update_beep(newBeep);
    beep_set(newBeep);
    savePreferences();
    if (print_key)
    {
      Serial.println("OK");
    }
  }
  else if (cmd.startsWith("AT+SET_MODE="))
  {
    String val = cmd.substring(12);
    int newMode = val.toInt();
    mode_g = newMode; // 设置全局模式变量
    update_mode(mode_g);
    savePreferences(); // 保存模式设置
    if (print_key)
    {
      Serial.println("OK");
    }
  }
  else if (cmd.startsWith("AT+SET_LEVEL="))
  {
    String val = cmd.substring(19);
    int newDifficulty = val.toInt();
    level_difficulty_g = newDifficulty;
    update_level(level_difficulty_g);
    savePreferences();
    if (print_key)
    {
      Serial.println("OK");
    }
  }
  else if (cmd.startsWith("AT+SET_SPEAKER="))
  {
    String val = cmd.substring(15);
    int speakerVal = val.toInt();
    if (speakerVal == 0 || speakerVal == 1)
    {
      speaker_g = (speakerVal == 1); // 设置全局语音开关变量
      // update_voice_state(speaker_g);
      savePreferences(); // 保存设置
      if (print_key)
      {
        Serial.println("OK");
      }
    }
    else
    {
      if (print_key)
      {
        Serial.println("ERROR: Invalid value (must be 0 or 1)");
      }
    }
  }
  else if (cmd == "AT+SELFTEST")
  {
    if (print_key)
    {
      Serial.println("== Running Self Test ==");
    }

    // 2. 测试电磁铁（假设只测试1个）
    setElectromagnet(1);
    controlElectromagnet(true);
    delay(200);
    setElectromagnet(2);
    controlElectromagnet(true);
    delay(200);
    setElectromagnet(3);
    controlElectromagnet(true);
    delay(200);
    setElectromagnet(4);
    controlElectromagnet(true);
    delay(200);
    setElectromagnet(5);
    controlElectromagnet(true);
    delay(500);
    setElectromagnet(1);
    controlElectromagnet(false);
    delay(200);
    setElectromagnet(2);
    controlElectromagnet(false);
    delay(200);
    setElectromagnet(3);
    controlElectromagnet(false);
    delay(200);
    setElectromagnet(4);
    controlElectromagnet(false);
    delay(200);
    setElectromagnet(5);
    controlElectromagnet(false);
    if (print_key)
    {
      Serial.println("[OK] Magnet test");
    }

    delay(1000);

    // 3. 测试蜂鸣器
    playBuzzer(beepLevel_g, 1000, 500);
    if (print_key)
    {
      Serial.println("[OK] Buzzer test");
    }

    delay(1000);

    // 4. 测试 WS2812（变色）
    setConstantColor(0, 255, 0, 0);
    delay(1000);
    setConstantColor(0, 0, 255, 0);
    delay(1000);
    setConstantColor(0, 0, 0, 255);
    delay(1000);
    turnOffLED(0);
    if (print_key)
    {
      Serial.println("[OK] WS2812 test");
    }

    delay(1000);

    // 5. 测试步进电机运动
    drawSquare(5, 5, 300);
    if (print_key)
    {
      Serial.println("[OK] MOTOR test");
    }

    if (print_key)
    {
      Serial.println("== Self Test Complete ==");
    }
  }
  else if (cmd.startsWith("AT+SET_WIFI="))
  {                                 // 新增Wi-Fi连接指令
    String val = cmd.substring(12); // 提取SSID和密码
    int commaIndex = val.indexOf(',');
    if (commaIndex != -1)
    {
      String ssid = val.substring(0, commaIndex);
      String password = val.substring(commaIndex + 1);

      // 连接Wi-Fi
      WiFi.begin(ssid.c_str(), password.c_str());

      if (print_key)
      {
        Serial.print("Connecting to WiFi");
      }
      int attempts = 0;
      while (WiFi.status() != WL_CONNECTED && attempts < 30)
      { // 最多等待30秒
        delay(500);
        if (print_key)
        {
          Serial.print(".");
        }
        attempts++;
      }

      if (WiFi.status() == WL_CONNECTED)
      {
        wifi_status_g = true;
        if (print_key)
        {
          Serial.println("\nWiFi connected!");
          Serial.print("IP Address: ");
          Serial.println(WiFi.localIP());
        }
        wifi_name_g = ssid;
        ip_g = WiFi.localIP().toString();
        ;
        if (print_key)
        {
          Serial.println("OK");
        }
      }
      else
      {
        if (print_key)
        {
          Serial.println("\nERROR: Failed to connect to WiFi");
        }
      }
    }
    else
    {
      if (print_key)
      {
        Serial.println("ERROR: Invalid WiFi command format. Use AT+SET_WIFI=<SSID>,<PASSWORD>");
      }
    }
  }
  else if (cmd == "AT+DISCONNECT_WIFI")
  { // 新增Wi-Fi断开指令
    WiFi.disconnect();
    wifi_status_g = false;
    if (print_key)
    {
      Serial.println("WiFi disconnected!");
      Serial.println("OK");
    }
  }
  else if (cmd.startsWith("AT+DEBUG_OFF"))
  {
    print_key = 0;
    if (print_key)
    {
      Serial.println("DEBUG OFF");
    }
  }
  else if (cmd.startsWith("AT+DEBUG_ON"))
  {
    print_key = 1;
    if (print_key)
    {
      Serial.println("DEBUG ON");
    }
  }
  else
  {
    if (print_key)
    {
      Serial.println("ERROR: Unknown command");
    }
  }
}
